#pragma once
#include <unistd.h>
#include <signal.h>
#include "Common.hpp"
#include "Log.hpp"
#include <sys/stat.h>
#include <fcntl.h>

using namespace myLog;

//int daemon(int nochdir, int noclose);

int Daemon(int nochdir, int noclose){
    //先显示忽略掉一些信号，信号是可以被继承给子进程的！
    signal(SIGCHLD, SIG_IGN);
    signal(SIGPIPE, SIG_IGN);

    if(fork() > 0)
        exit(OK);

    //守护进程，起始就是另开一个会话，让服务器进入这个会话，不受其他影响
    //需要调用接口setsid，但是这个接口有一个问题就是，调用它的不能是组长进程
    //所以，常见的方案就是，创建子进程，子进程来进行操作

    //这个接口自动的把当前进程搞到一个新的会话下 -> 就是守护进程
    pid_t id = setsid();

    //在系统接口daemon下，如果第一个参数被设置为0，那么就需要切换工作路径到根目录下
    if(nochdir == 0) chdir("/");

    //一般来讲，服务器是不需要向所谓的显示器进行打印的！但是，我们又不希望直接关掉对应的0，1，2文件描述符
    //所以，可以重定向到一个文件，即 "/dev/null"文件 这个文件可以向里面写入，也可以读，但是读不出来，写进去会被丢掉

    //在系统接口daemon下，如果第二个参数被设置为0，就需要把stdout、stderr、stdin重定向到 "/dev/null"
    //重定向使用的接口时dup2！
    if(noclose == 0){
        int fd = open("/dev/null", O_RDWR);
        if(fd < 0){
            LOG(LogLevel::FATAL) << "open /dev/null error";
            exit(OPEN_ERROR);
        }
        dup2(fd, 0);
        dup2(fd, 1);
        dup2(fd, 2);
        close(fd);
    }

    return (id == -1) ? -1 : 0;
}


//守护进程

